/*
 * Copyright 2005-2013 finalist.cn. All rights reserved.
 * Support: http://www.finalist.cn
 * License: http://www.finalist.cn/license
 */
package com.finalist.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.LockModeType;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.finalist.Principal;
import com.finalist.Setting;
import com.finalist.dao.MemberDao;
import com.finalist.entity.Admin;
import com.finalist.entity.Member;
import com.finalist.entity.Member.Gender;
import com.finalist.entity.Member.MaritalStatus;
import com.finalist.entity.Product;
import com.finalist.service.MemberService;
import com.finalist.util.SettingUtils;

/**
 * Service - 会员
 * 
 * @author Finalist IT Group
 * @version 3.0
 */
@Service("memberServiceImpl")
public class MemberServiceImpl extends BaseServiceImpl<Member, Long> implements MemberService
{

    @Resource(name = "memberDaoImpl")
    private MemberDao memberDao;

    @Resource(name = "memberDaoImpl")
    public void setBaseDao(MemberDao memberDao)
    {
        super.setBaseDao(memberDao);
    }

    @Override
    @Transactional(readOnly = true)
    public boolean usernameExists(String username)
    {
        return this.memberDao.usernameExists(username);
    }

    @Override
    @Transactional(readOnly = true)
    public boolean phoneExists(String phone)
    {
        return this.memberDao.phoneExists(phone);
    }

    @Override
    @Transactional(readOnly = true)
    public boolean usernameDisabled(String username)
    {
        Assert.hasText(username);
        Setting setting = SettingUtils.get();
        if (setting.getDisabledUsernames() != null)
        {
            for (String disabledUsername : setting.getDisabledUsernames())
            {
                if (StringUtils.containsIgnoreCase(username, disabledUsername))
                {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    @Transactional(readOnly = true)
    public boolean emailExists(String email)
    {
        return this.memberDao.emailExists(email);
    }

    @Override
    @Transactional(readOnly = true)
    public boolean emailUnique(String previousEmail, String currentEmail)
    {
        if (StringUtils.equalsIgnoreCase(previousEmail, currentEmail))
        {
            return true;
        }
        else
        {
            if (this.memberDao.emailExists(currentEmail))
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }

    @Override
    public void save(Member member, Admin operator)
    {
        Assert.notNull(member);
        this.memberDao.persist(member);

        //        try
        //        {
        //            AuthenticateItf auth = new AuthenticateItf();
        //            String token = auth.askDisposableToken();
        //
        //            CommonItfReq req = new CommonItfReq();
        //            //todo 密码转换加密处理
        //            req.put("password", member.getPassword());
        //            req.put("username", member.getUsername());
        //            req.put("mobile", member.getPhone());
        //            req.put("email", member.getEmail());
        //            req.put("token", token);
        //            auth.register(req);
        //
        //        }
        //        catch (Exception e)
        //        {
        //            e.printStackTrace();
        //        }

        if (member.getBalance().compareTo(new BigDecimal(0)) > 0)
        {
        }
    }

    @Override
    public void update(Member member, Integer modifyPoint, BigDecimal modifyBalance, String depositMemo, Admin operator)
    {
        Assert.notNull(member);

        this.memberDao.lock(member, LockModeType.PESSIMISTIC_WRITE);

        if (modifyPoint != null && modifyPoint != 0 && member.getPoint() + modifyPoint >= 0)
        {
            member.setPoint(member.getPoint() + modifyPoint);
        }

        if (modifyBalance != null && modifyBalance.compareTo(new BigDecimal(0)) != 0 && member.getBalance().add(modifyBalance).compareTo(new BigDecimal(0)) >= 0)
        {
            member.setBalance(member.getBalance().add(modifyBalance));
        }
        this.memberDao.merge(member);
    }

    @Override
    @Transactional(readOnly = true)
    public Member findByUsername(String username)
    {
        return this.memberDao.findByUsername(username);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Member> findListByEmail(String email)
    {
        return this.memberDao.findListByEmail(email);
    }

    /**
     * 根据手机号查找会员
     * 
     * @param phone
     *            手机号
     * @return 会员，若不存在则返回null
     */
    @Override
    @Transactional(readOnly = true)
    public Member findByPhone(String phone)
    {
        return this.memberDao.findByPhone(phone);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Object[]> findPurchaseList(Date beginDate, Date endDate, Integer count)
    {
        return this.memberDao.findPurchaseList(beginDate, endDate, count);
    }

    @Override
    @Transactional(readOnly = true)
    public boolean isAuthenticated()
    {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        if (requestAttributes != null)
        {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            Principal principal = (Principal) request.getSession().getAttribute(Member.PRINCIPAL_ATTRIBUTE_NAME);
            if (principal != null)
            {
                return true;
            }
        }
        return false;
    }

    @Override
    @Transactional(readOnly = true)
    public Member getCurrent()
    {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        if (requestAttributes != null)
        {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            Principal principal = (Principal) request.getSession().getAttribute(Member.PRINCIPAL_ATTRIBUTE_NAME);
            if (principal != null)
            {
                return this.memberDao.find(principal.getId());
            }
        }
        return null;
    }

    @Override
    @Transactional(readOnly = true)
    public String getCurrentUsername()
    {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        if (requestAttributes != null)
        {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            Principal principal = (Principal) request.getSession().getAttribute(Member.PRINCIPAL_ATTRIBUTE_NAME);
            if (principal != null)
            {
                return principal.getUsername();
            }
        }
        return null;
    }

    @Override
    public Member getMemberByOpenId(String openId)
    {
        return this.memberDao.findByOpenId(openId);
    }

    @Override
    public Member openIdExists(String openId)
    {
        // TODO Auto-generated method stub
        return this.memberDao.openIdExists(openId);
    }

    @Override
    @Transactional(readOnly = true)
    public Member getMemberByNameAndMobile(String username, String mobile)
    {
        return this.memberDao.findByUsernameAndMobile(username, mobile);
    }

    @Override
    public Member findLoginMember(List<String> list)
    {

        return this.memberDao.findLoginMember(list);
    }

	@Override
	public Member findByOpenId(String openId) {
		return this.memberDao.findByOpenId(openId);
	}

	@Override
	public Member findByUnionId(String unionId) {
		return memberDao.findByunionId(unionId);
	}

	@Override
	public List<Member> findByProduct(Product product,int page) {
		List<Object[]>  o = memberDao.findByProduct(product,page);
		
		if(o!=null && o.size()>0){
			List<Member> members = new ArrayList<Member>();
			for(int i = 0 ; i < o.size() ; i++){
				Member member =  new Member();
				member.setId((Long)o.get(i)[0]);
				member.setUsername(o.get(i)[1]==null?"":o.get(i)[1].toString());
				member.setGender(o.get(i)[2]==null?Gender.male:(Gender)o.get(i)[2]);
				member.setMaritalStatus(o.get(i)[3]==null?MaritalStatus.secretive:(MaritalStatus)o.get(i)[3]);
				member.setIndustry(o.get(i)[4]==null?"":o.get(i)[4].toString());
				member.setSchool(o.get(i)[5]==null?"":o.get(i)[5].toString());
				member.setHometown(o.get(i)[6]==null?"":o.get(i)[6].toString());
				member.setHobby(o.get(i)[7]==null?"":o.get(i)[7].toString());
				member.setMemo(o.get(i)[8]==null?"":o.get(i)[8].toString());
				member.setHeadImgUrl(o.get(i)[9]==null?"":o.get(i)[9].toString());
				members.add(member);
			}
			return members;
		}
		return null;
	}

}
